package pl.edu.agh.inpema.components.analyzers.linkAnalyzer;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;

import pl.edu.agh.inpema.components.analyzers.linkAnalyzer.data.Link;
import pl.edu.agh.inpema.components.analyzers.linkAnalyzer.data.LinkDate;
import pl.edu.agh.inpema.core.components.AnalyzerUtil;
import pl.edu.agh.inpema.core.model.AnalyzeResult;
import pl.edu.agh.inpema.core.model.Analyzer;
import pl.edu.agh.inpema.core.model.Message;

public class LinkAnalyzer extends Thread implements Analyzer {
	
	private boolean isRunning = false;
	private boolean queueEmpty = false;
	private boolean isError = false;
	
	private AnalyzerUtil analyzerUtil;
	
	private static Logger logger = Logger.getLogger(LinkAnalyzer.class);
	
	public LinkAnalyzer() {
		
	}
	
	public int compareResults(AnalyzeResult result1, AnalyzeResult result2) {
		List<Object> p1LinksObj = this.analyzerUtil.getResultObjects(result1.getAnalyzeResultDataId(), Link.class);
		List<Object> p2LinksObj = this.analyzerUtil.getResultObjects(result2.getAnalyzeResultDataId(), Link.class);
		
		Set<String> profile1Links = new HashSet<String>();
		for (Object obj : p1LinksObj)
			profile1Links.add(((Link) obj).getLink());
		Set<String> profile2Links = new HashSet<String>();
		for (Object obj : p2LinksObj)
			profile2Links.add(((Link) obj).getLink());
		int result = 0;
		for (Object p1LinkObj : p1LinksObj) {
			Link p1link = (Link) p1LinkObj;
			for (Object p2LinkObj : p2LinksObj) {
				Link p2link = (Link) p2LinkObj;
				if (p2link.getLink().equals(p1link.getLink())) {
					//p1link.getLinkDates()
					result += Math.min(p1link.getLinkDates().size(), p2link.getLinkDates().size());
				}
			}
		}
		/*for (String link : profile1Links) {
			if (profile2Links.contains(link)) {
				result++;
			}
		}*/
		return result;
	}

	public boolean isAnalyzerRunning() {
		return this.isRunning;
	}

	public void startAnalyzer() {
		this.isRunning = true;
		this.start();

	}

	public boolean stopAnalyzer() {
		this.isRunning = false;
		return this.isError;
	}
	
	public void run() {
		this.isError = false;
		while (this.isRunning || !queueEmpty) {
			Message message = this.analyzerUtil.getNextMessage();
			
			if (message == null) {
				queueEmpty = true;
				continue;
			}
			queueEmpty = false;
			
			Integer profileId = message.getProfileId();
			
			String date = message.getField(Message.FIELD_DATE);
			String text = message.getField(Message.FIELD_TEXT);
			
			String[] words = text.split(" ");
			for (String word : words) {
				if (word.length() > 5) {
					if ("http:".equals(word.substring(0, 5))) {
						logger.info("LNK: '" + word + "'");
						this.putLinkToProfile(profileId, word, Long.valueOf(date));
					}
				}
			}
		}
	}
	
	public Class[] getDataClasses() {
		Class[] dataClass = { 
				Link.class,
				LinkDate.class
		};
		return dataClass;
	}
	
	private void putLinkToProfile(int profileId, String word, long date) {
		Integer resultId = this.analyzerUtil.getResultId(profileId);
		List<Object> linksObjList = this.analyzerUtil.getResultObjects(resultId, Link.class);
		Link link = null;
		if (linksObjList == null || linksObjList.size() == 0) {
			link = new Link();
			link.setResultId(resultId);
			link.setLink(word);
			this.analyzerUtil.addResultObject(link);
		} else {
			for (Object obj : linksObjList) {
				Link l = (Link) obj;
				if (l.getLink().equals(word)) {
					link = l;
					break;
				}
			}
			if (link == null) {
				link = new Link();
				link.setResultId(resultId);
				link.setLink(word);
				this.analyzerUtil.addResultObject(link);
			}
		}
		LinkDate linkDate = new LinkDate();
		linkDate.setDate(date);
		linkDate.setLink(link);
		link.getLinkDates().add(linkDate);
		//this.dataBase.addResultObject(this.name, linkDate);
	}
	
	public void setAnalyzerUtil(AnalyzerUtil analyzerUtil) {
		this.analyzerUtil = analyzerUtil;
	}
	
	public AnalyzerUtil getAnalyzerUtil() {
		return this.analyzerUtil;
	}
}
